package hku.cs.eclunuo.marker;

import hku.cs.eclunuo.LunuoPlugin;
import hku.cs.eclunuo.views.Rank;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IType;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.ui.editors.text.TextFileDocumentProvider;
import org.eclipse.ui.texteditor.IDocumentProvider;

public class SusMarker {
	public final static String MARKER_ID = LunuoPlugin.PLUGIN_ID
			+ ".suspicious";
	public final static String RANK = "rank";
	public final static String SUSPICIOUS = "suspicious";

	private IJavaProject javaProject;

	public SusMarker(IJavaProject jp) {
		javaProject = jp;
	}

	public boolean deleteMarkers() {
		try {
			javaProject.getProject().deleteMarkers(MARKER_ID, false,
					IResource.DEPTH_INFINITE);
			return true;
		} catch (CoreException e) {
			e.printStackTrace();
			return false;
		}
	}

	private class Location {
		int charstart;
		int charend;

		public Location(int charstart, int charend) {
			super();
			this.charstart = charstart;
			this.charend = charend;
		}

	}

	public void addMarkers(List<Rank> ranks) {
		deleteMarkers();
		final int firstRank;
		if(ranks.size()>0)
			firstRank = ranks.get(0).getRank();
		else 
			return;
		try {
			List<Rank> cons = new ArrayList<Rank>(ranks.size());
			for (Rank r : ranks) {
				
				if(cons.contains(r))
					continue;
				else
					cons.add(r);
				
				final int rank = r.getRank();
				final String suspicious = r.getSuspicious();
				final String className = r.getKlass();
				final int line = r.getLine();
				
				IType type = javaProject.findType(className.split("\\$")[0]);
				if(type==null)
					continue;
				final IResource jR = type.getResource();
				
				
				IWorkspaceRunnable runnable = new IWorkspaceRunnable() {
					public void run(IProgressMonitor monitor)
							throws CoreException {
						File cF = jR.getLocation().toFile();
//						Location loc = findLocation(cF, line);
						
						IDocumentProvider provider = new TextFileDocumentProvider();
						provider.connect((IFile)jR);
						IDocument document = provider.getDocument((IFile)jR);
						int start = 0 , end = 0;
						try {
							start = document.getLineOffset(line-1);
							end = document.getLineOffset(line);
						} catch (BadLocationException e) {
							e.printStackTrace();
						}
						
						final Location loc = new Location(start, end);
						
						IMarker marker = jR.createMarker(MARKER_ID);
						
						
						marker.setAttribute(RANK, rank);
						marker.setAttribute(SUSPICIOUS, String.valueOf(suspicious));
						float sus = Float.parseFloat(suspicious.split(" ")[0]);
						if(sus<=0)
							marker.setAttribute(IMarker.SEVERITY, new Integer(
								IMarker.SEVERITY_INFO));
						else if(rank==firstRank)
							marker.setAttribute(IMarker.SEVERITY, new Integer(
									IMarker.SEVERITY_ERROR));
						else
							marker.setAttribute(IMarker.SEVERITY, new Integer(
									IMarker.SEVERITY_WARNING));

						marker.setAttribute(IMarker.LOCATION, line + " line");
						marker.setAttribute(IMarker.CHAR_START, new Integer(
								loc.charstart));
						marker.setAttribute(IMarker.CHAR_END, new Integer(
								loc.charend));
						// marker.setAttribute(IMarker.MESSAGE,
						// "The suspicious line");
					}
				};
				jR.getWorkspace().run(runnable, null);
			}
		} catch (CoreException e) {
			e.printStackTrace();
		}
	}

	private Location findLocation(File cf, int line) {
		BufferedReader fr = null;
		try {
			fr = new BufferedReader(new FileReader(cf));
			int i = 1;
			int charstart = 0;
			int charend = 0;
			while (i < line) {
				String s = fr.readLine();
				charstart += s.length() + 1;
				i++;
			}
			charend = charstart + fr.readLine().length();
			return new Location(charstart, charend);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (fr != null)
				try {
					fr.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
		}
		return null;
	}
}
